#include <vcl.h>
#include <registry.hpp>
#pragma hdrstop

#include <EIC.h>
#include <stdio.h>
#include "uFncGDI.h"
#include "uEtat.h"
#include "uRtf.h"
#include "GenEtatVer.h"

//---------------------------------------------------------------------------
//#define AFFICHE_TPS

#pragma package(smart_init)
#define MODULE_TAG MODULE_TAG_ETAT
CGlobal ETATAPI *Glob = NULL;

#define ECRIT_AUTORISE( Val, bEcriture) if( Reg->ValueExists(#Val) && !bEcriture) Glob->Val = Reg->ReadBool( #Val); \
                                        else                                      Reg->WriteBool( #Val, Glob->Val); \
                                        TRACEF( TAGL, #Val"[%d]", (int)Glob->Val);

void InitReg( bool bEcriture)
{
    try{
        AnsiString Trace = "TRACE", TraceDate = "TRACE_DATE";
        bool bTrace = (Glob->TraceF == TRACEF_OK);
        TRegistry *Reg = new TRegistry();
        Reg->RootKey = HKEY_CURRENT_USER;
        Reg->OpenKey("SoftWare\\eic\\etat", true);
        if( Reg->ValueExists(Trace) && !bEcriture)  bTrace = Reg->ReadBool( Trace);
        else                                          Reg->WriteBool( Trace, bTrace);

        if( bTrace)
        { // Vérif de l'utilité de faire un TRACE
          if( bEcriture || !Reg->ValueExists(TraceDate))
            Reg->WriteDateTime( TraceDate, TDateTime::CurrentDateTime());
          else{
            TDateTime dt = Reg->ReadDateTime( TraceDate);
            if( dt + TDateTime( 12, 0, 0, 0) < TDateTime::CurrentDateTime())
            {
              bTrace = false;
              Reg->WriteBool( Trace, bTrace);
              Reg->DeleteValue(TraceDate);
            }
          }
        }else if( Reg->ValueExists(TraceDate))
          Reg->DeleteValue(TraceDate);


        if( bTrace)
        {
            DeleteFile( Glob->ficTrace);
            Glob->TraceF = TRACEF_OK;
            TRACEF( 0, "Version [" _VER_szVER_ETAT "] Etat[%d.%d]", _VER_iMAJOR_FILE_ETAT, _VER_iMINOR_FILE_ETAT);
        }else
            Glob->TraceF = TRACEF_Vide;
        Reg->WriteString( "TRACEFile", Glob->ficTrace);

        ECRIT_AUTORISE( AutoriseTextParBmp, bEcriture);
//        ECRIT_AUTORISE( SortieTextesVerticauxParBmp, bEcriture);
    #define cle "_SortieTextesVerticauxParBmp"
        if( Reg->ValueExists(cle) && !bEcriture) Glob->SortieTextesVerticauxParBmp = Reg->ReadBool( cle);
        else                                      Reg->WriteBool( cle, Glob->SortieTextesVerticauxParBmp);
        TRACEF( TAGL, cle"[%d]", (int)Glob->SortieTextesVerticauxParBmp);
    #undef cle
    #define cle "OLETabMethode"
        if( Reg->ValueExists( cle) && !bEcriture) Reg->ReadBinaryData( cle, Glob->OLETabMethode, sizeof( Glob->OLETabMethode));
        else                                      Reg->WriteBinaryData( cle, Glob->OLETabMethode, sizeof( Glob->OLETabMethode));
        TRACEF( TAGL, cle" [%d;%d;%d;%d;%d]", Glob->OLETabMethode[0], Glob->OLETabMethode[1], Glob->OLETabMethode[2], Glob->OLETabMethode[3], Glob->OLETabMethode[4]);
    #undef cle

        Reg->CloseKey();
        delete Reg;
    }catch(...){}
}

void ETATAPI EtatInitialize(bool bVersionDeDemonstration, bool GestionEnvoiGED)
{
    try{
        Glob->cptInit ++;
        if( Glob->cptInit != 1) return;

            // Init du fichier trace en premier
        Glob->ficTrace = NULL;
        Glob->AutoriseTextParBmp = false;
//        Glob->AutoriseOLEByViewObject = true;
        Glob->SortieTextesVerticauxParBmp = false;

        int i;
        ChkSDK( TAGL, (i = ::GetTempPath( 0, NULL)), 0);
        Glob->szTempPath = (char*)::_GlobalAlloc(TAGL, GPTR, i+1);
        ChkSDK( TAGL, ::GetTempPath( i, Glob->szTempPath), 0);

        Glob->ficTrace = (char*)::_GlobalAlloc(TAGL, GPTR, i+9+1);
        ::GetTempFileName( Glob->szTempPath, "ETA", 1, Glob->ficTrace);
        char* s = strstr( strupr(Glob->ficTrace), ".TMP");
        *(s+1) = 'L'; *(s+2) = 'O'; *(s+3) = 'G';

        InitReg( false);

        bool hPckEtat = ::GetModuleHandle("PckEtat.bpl");
        Glob->LanceEnConception = ::GetModuleHandle("GenEtat.exe");
        ASSERT( hPckEtat || Glob->LanceEnConception);
        Glob->hRgnTmp1 = ::_CreateRectRgn( TAGL, 0,0,0,0);
        Glob->hRgnTmp2 = ::_CreateRectRgn( TAGL, 0,0,0,0);
        Glob->CurrentDir = GetCurrentDir();
        Glob->asD_NS = D_NS;
        Glob->SessionName = EmptyStr;
        for( int i = 1; i <= Glob->asD_NS.Length(); i++)
        {
            if( Glob->asD_NS[i] == '.')
                Glob->asD_NS[i] = DecimalSeparator;
        }
        if( !Glob->Rtf) Glob->Rtf = new CRtf();
        Glob->bVersionDeDemonstration = bVersionDeDemonstration;
        GED_gGestionEnvoi = GestionEnvoiGED;
        InitDCEcran();
    }CATCH_EXCEPTION( TAG( 1))
}
void ETATAPI EtatUnInitialize()
{
    try{
        Glob->cptInit--;
        if( Glob->cptInit) return;

        ::_DeleteObject( TAGL, Glob->hRgnTmp1); Glob->hRgnTmp1 = 0;
        ::_DeleteObject( TAGL, Glob->hRgnTmp2); Glob->hRgnTmp2 = 0;
        DestroyDCEcran();
        if( Glob->Rtf)        {delete Glob->Rtf;               Glob->Rtf = NULL;}

        ::_GlobalFree(TAGL, Glob->szTempPath); Glob->szTempPath = NULL;
        Glob->CurrentDir.SetLength( 0);
        Glob->asD_NS.SetLength( 0);
        Glob->SessionName.SetLength( 0);
        Glob->TraceF = TRACEF_Vide;
        ::_GlobalFree(TAGL, Glob->ficTrace);   Glob->ficTrace = NULL;
    }CATCH_EXCEPTION( TAG( 2))
}

int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)
{
    switch( reason)
    {   case DLL_PROCESS_ATTACH :
            try{
                Glob = new CGlobal();
                Glob->cptInit = 0;
                TRACE( "Glob [%p]", Glob);
                Glob->TraceF = TRACEF_Vide;
                Glob->bConception = true;
                Glob->EICPrinter = Glob->OldEICPrinter = NULL;
                Glob->OldResolutionX = D_NS;
                Glob->OldResolutionY = D_NS;
                Glob->ResolEcran = 96;
                Glob->ResolutionX = Screen->PixelsPerInch;
                Glob->ResolutionY = Screen->PixelsPerInch;
                Glob->nRectifPourDessin = RECTIF_DEFAUT;
                Glob->LargBarreGauchePixels = ::GetSystemMetrics( SM_CYCAPTION);
                Glob->hDCEcran = NULL;
                Glob->hThread = 0;
                Glob->LanceEnConception = !::GetModuleHandle("pckEtat.bpl");
                Glob->hRgnTmp1 = NULL;
                Glob->hRgnTmp2 = NULL;
                Glob->szTempPath = NULL;
                Glob->Rtf = NULL;
                for( OLEMethode i = OLE_Min; i <= OLE_Max; i++)
                    Glob->OLETabMethode[i] = i;
                Glob->OLEInitialise = 0;
            }CATCH_EXCEPTION( TAG( 3))
            break;
        case DLL_PROCESS_DETACH :
            try{
                delete Glob;
                Glob = NULL;
            }CATCH_EXCEPTION( TAG( 4))
            break;
    }
    return 1;
}

//---------------------------------------------------------------------------

void __fastcall InitDCEcran( )
{
    try{
        if( !Glob->hDCEcran)
        {
            Glob->hDCEcran = ::_CreateDC( TAGL, "DISPLAY", NULL, NULL, NULL);
            ChkSDK( TAGL, ::SetWindowExtEx( Glob->hDCEcran, Glob->ResolEcran, Glob->ResolEcran, NULL), false);
        }
    }CATCH_EXCEPTION( TAG( 5))
}
void __fastcall DestroyDCEcran( )
{
    try{
        if( Glob->hDCEcran)
        {
            ::_DeleteDC( TAGL, Glob->hDCEcran);
            Glob->hDCEcran = NULL;
        }
    }CATCH_EXCEPTION( TAG( 6))
}

bool __fastcall PushResolutionAndPutEcran()
{
    if( Glob->ResolutionX != Glob->ResolEcran)
    {
        Glob->OldResolutionX = Glob->ResolutionX;
        Glob->OldResolutionY = Glob->ResolutionY;
        Glob->OldEICPrinter = Glob->EICPrinter;
        Glob->ResolutionY = Glob->ResolEcran;
        Glob->ResolutionX = Glob->ResolEcran;
        Glob->EICPrinter = NULL;
        return true;
    }
    return false;
}
bool __fastcall PopResolution()
{
    if( IsPushedResolution())// || Glob->OldEICPrinter)
    {
        Glob->ResolutionX = Glob->OldResolutionX;
        Glob->ResolutionY = Glob->OldResolutionY;
        Glob->EICPrinter = Glob->OldEICPrinter;
        Glob->OldResolutionX = D_NS;
        Glob->OldResolutionY = D_NS;
        Glob->OldEICPrinter = NULL;
        return true;
    }
    return false;
}
bool __fastcall IsPushedResolution()
{
    return( Glob->OldResolutionX != D_NS);
}

//---------------------------------------------------------------------------
__fastcall MyCBarre::~MyCBarre()
{
#ifdef AFFICHE_TPS
    unsigned short hour, min, sec, msec;
    TDateTime T = Time() - TimeDebut;
    T.DecodeTime(&hour, &min, &sec, &msec);
    ShowMessage( T.FormatString("hh:nn:ss:") + msec);
#endif
}
__fastcall MyCBarre::MyCBarre(const AnsiString &asMsg, bool bAnnule):CBarre()
{
  try{
    Titre = "Veuillez patienter ...";
    Messages = asMsg;
    Open();
    AfficherBoutonAnnuler = bAnnule;
#ifdef AFFICHE_TPS
    TimeDebut = Time();
#endif
    }catch(...){}
}

void ETATAPI DisplayExceptionNonGeree( EICTag tag, const AnsiString &s)
{
    TRACEF( tag, AnsiString("Exception non gérée" + s).c_str());
    EUser *e = new EUser( tag, "Exception non gérée" + s);
    EICDisplayException( tag, *e);
    delete e;
}

void TraiteLastError(EICTag TAG, const AnsiString &s)
{
  #ifdef _DEBUG
    AfficheLastErrorT( AnsiString("TAG[")+TAG_MODULE( TAG)+"-"+ TAG_TAG( TAG)+"] " + s);
  #else
   if( TRACEF == TRACEF_OK)
   {
       LPVOID lpMsgBuf;
       int LastError = GetLastError( );
       FormatMessage(
              FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
              NULL,
              LastError,
              MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
              (LPTSTR) &lpMsgBuf,
              0,
              NULL
              );
       TRACEF( TAG, "LastError : [%s] [%d] %s", s.IsEmpty()?"Erreur":s.c_str(), LastError, lpMsgBuf);
       LocalFree( lpMsgBuf );
    }
  #endif
}

void __cdecl TRACEF_Vide( EICTag Tag, const char* szFormat, ...){}
void __cdecl TRACEF_OK( EICTag Tag, const char* szFormat, ...)
{
    if( Glob && strlen( Glob->ficTrace))
    {
        char szBuff[ 500];
        va_list marker;
        FILE* f;

        f = fopen( Glob->ficTrace, "a");

        fprintf( f, "TAG[%d-%d] ", TAG_MODULE( Tag), TAG_TAG( Tag));
        ASSERT( szFormat);
        va_start( marker, szFormat );
        vfprintf( f, szFormat, marker );
        fputs( "\r\n", f);

        fclose( f);
    }
}
//----------------------------------------------------------------------------

void ETATAPI __fastcall DestroyLstStylesModif( TStringList *pLstStylesModif)
{
  try
  {
    EICStyle *Style = NULL;
    if( pLstStylesModif)
    {
      while( pLstStylesModif->Count)
      {
        Style = (EICStyle*)pLstStylesModif->Objects[0];
        if( Style) { delete  Style; Style = NULL;}
        pLstStylesModif->Delete(0);
      }
      delete pLstStylesModif; pLstStylesModif = NULL;
    }
  }
  catch( Exception &e)
  {
    EICDisplayException( TAGL, e);
  }
}
//---------------------------------------------------------------------------
bool IsValeurSignificative( const AnsiString &s)
{
    return ( !s.IsEmpty() && (s != L_NS) && (s != D_NS) && (s != Glob->asD_NS) );
}
bool IsValeurSignificative( double d)
{
    return ( (d != L_NS) && (d != D_NS) && (AnsiString(d) != Glob->asD_NS) );
}
//---------------------------------------------------------------------------

void OLEInitialize()
{
    if( !Glob->OLEInitialise)
    {
        HRESULT h = OleInitialize(NULL);
        if( h != S_FALSE) ChkOLE( TAGL, h);
    }
    Glob->OLEInitialise++;
}
//---------------------------------------------------------------------------

void OLEUnInitialize()
{
    Glob->OLEInitialise--;

    if( !Glob->OLEInitialise)
    {
        OleUninitialize();
    }
}
//---------------------------------------------------------------------------
AnsiString __fastcall RemplaceCharInvalidate(AnsiString asStringAValider)
{
    try {
        char* szFileCharInvalids ="\\/:*?\"<>|";
        for( int i=1; i <= asStringAValider.Length(); i++)
        {
            if( strchr( szFileCharInvalids, asStringAValider[i])) asStringAValider[i] = '_';
        }
    } catch( Exception &e)
    {
        EICDisplayException( TAGL, e);
    }
    return asStringAValider;
}
